-- 2022-8-15

---[[ 错误处理和异常

    -- 对于大多数应用而言 我们无须在Lua代码中做任何错误处理 应用程序本身会负责处理这类问题
    -- 所有的Lua语言的行为都是由应用程序的一次调用而触发的 这类函数通常是要求Lua语言执行一段代码
    -- 如果执行中发生了错误 那么调用会返回一个错误代码 以便应用程序采取适当的行为来处理错误
    -- 当独立解释器在发生错误时 主循环会打印错误信息 然后继续显式提示符 并等待执行指定的命令

    -- 不过 如果要在Lua代码在处理错误 那么就应该使用函数pcall(protected call)来封装代码

    -- 假设要执行一段Lua代码并捕获(try-catch)执行中发生的所有错误 那么首先需要将这段代码封装到一个函数中 这个函数通常是一个匿名函数
    -- 之后 提供pcall来调用这个函数
    local ok,msg = pcall(function ()
        -- -- some code
        -- if --unexpected condition
        -- then -- error()
        -- end
        -- -- some code
        -- print(a[i]) -- 潜在错误: a可能不是一个表
        -- -- some code
        -- if ok then  -- 执行被保护的代码时没有错误发生
        --     -- regular code
        -- else   -- 执行被保护的代码时有错误发生 进行恰当的处理
        --     -- error-handling code
        -- end
    end)

    -- 函数pcall会以一种保护模式(protected mode)来调用它的第1个参数 以便捕获该函数执行中的错误
    -- 无论是否有错误发生 函数pcall都不会引发错误
    -- 如果没有错误发生 那么pcall返回true及被调用函数(作为pcall的第一个参数传入)的所有返回值 否则 则返回false及错误信息

    -- 使用"错误信息"的命名方式可能会让人误解错误信息必须是一个字符串 因此称之为错误对象(error object)可能更好
    -- 这主要是因为函数pcall能够返回传递给error的任意Lua语言类型的值
    local status,err = pcall(function ()
        error({code=121})
    end)
    print(err.code)
    -- 这些机制为我们提供了在Lua语言中进行异常处理的全部 我们可以通过error来抛出异常(throw an exception) 然后用函数pcall来捕获(catch)异常
    -- 而错误信息则用来标识错误的类型
--]]